home *** CD-ROM | disk | FTP | other *** search
/ Mac Expert 1995 Winter / Mac Expert - Winter 95.iso / Les fichiers / Communications / Divers / DinkClass ƒ / DinkClass / DAppEventSupport.c next >
Encoding:
Text File  |  1992-12-31  |  9.7 KB  |  395 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        DAppEventSupport.cp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Mark Gross
  7.  
  8.     Copyright:    © 1992 by Applied Technical Software, all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>    12/31/92    MTG        making the code conditionaly compiled so         that I am
  13.                                     always working with a current         version in either think c
  14.                                     or MPW C++
  15.          <5>    11/14/92    MTG        Bringing the C++ version up to date WRT the ThinkC version.
  16.          <4>     9/20/92    MTG        bringing the C++ version up to date with the THINKC viersion
  17.          <3>      8/9/92    MTG        merging changes from the ThinkC version
  18.          <2>      8/8/92    MTG        fixing warnings
  19.  
  20.     To Do:
  21. */
  22.  
  23.  
  24. //
  25. // This file holds the impelemtation of the Event dispatch code for
  26. // the DApplication class.  It has the event object list maintence
  27. // code and the "first crack" methods for the various Events returned by WaitNextEvent
  28. // which do something important then sends the event on to the
  29. // event handler model.  The First Crack methods are NOT to do the work that
  30. // the DEventHandler method overrides are intended to do, just the
  31. // critical tasks which must be done befor the eventhandler can
  32. // do its job.
  33. //
  34.  
  35. #include "DApplication.h"
  36. #include "DEventHandler.h"
  37. #include "DDocument.h"
  38. #include <AppleEvents.h>
  39. #include <DinkUtils.h>
  40.  
  41. #define    kOSEvent    app4Evt
  42. #define    kSuspendResumeMessage    0x01
  43. #define    kMouseMovedMessage    0xFA
  44.  
  45.  
  46. void DApplication::EventLoop(void)
  47. {
  48.     long    gotEvent;
  49.     EventRecord    theEvent;
  50.     
  51.     while(fDone == FALSE)
  52.     {
  53.         gotEvent = WaitNextEvent( everyEvent, &theEvent, fSleepVal, NULL);
  54.  
  55.         gPassItOn = TRUE;
  56.         switch(theEvent.what) 
  57.         {
  58.             case nullEvent:
  59.                 NullEvent(&theEvent);
  60.                 break;
  61.     
  62.             case mouseDown:
  63.                 MouseDown(&theEvent);
  64.                 break;
  65.     
  66.             case activateEvt:// put the correct window in the front!!! and make it the mTarget!!
  67.                 ActivateEvt(&theEvent);
  68.                 break;
  69.     
  70.             case autoKey:
  71.             case keyDown:                    
  72.                 KeyDown(&theEvent);
  73.                 break;
  74.     
  75.             case diskEvt:
  76.                 DiskEvt(&theEvent);
  77.                 break;        
  78.                 
  79.             case kHighLevelEvent:
  80.                 HighLevelEvent(&theEvent);
  81.                 break;
  82.     
  83.             case kOSEvent:
  84.                 OSEvent(&theEvent);
  85.                 break;
  86.     
  87.             case updateEvt:
  88.                 UpdateEvt(&theEvent);
  89.                 break;
  90.             
  91.             default:
  92.                 //EnterMBStr("unknown event!!!");
  93.                 break;
  94.     
  95.         }// end big event switch!!
  96.  
  97.     }// end while mDone is still false
  98. }// end member function EventLoop
  99.  
  100.  
  101. //
  102. // The following section of code is the "First Crack" methods requiered
  103. // by the Macintosh os, and the DinkClass event handling architecture.
  104. //
  105.  
  106. void DApplication::MouseDown(EventRecord *theEvent)
  107. {
  108.     WindowPtr    theWindow;
  109.     short        partCode;
  110.     long        result;
  111.     
  112.     partCode = FindWindow( theEvent->where, &theWindow);
  113.     if( partCode == inMenuBar )
  114.     {
  115.         ClearMenus();
  116.         fTarget->SetUpMenues();
  117.         
  118.         result = MenuSelect(theEvent->where);
  119.         if(HiWrd(result) != 0)
  120.         {
  121.             fTarget->HandleMenuChoice(HiWrd(result), LoWrd(result) );
  122.             HiliteMenu(0);
  123.         }
  124.     }
  125.     else
  126.     {
  127.         if ( theWindow != FrontWindow() )
  128.             SelectWindow( theWindow);    // The resulting activate event will
  129.                                         // correctly set the ftarget of me in
  130.                                         // the Activate method bellow.
  131.          else
  132.             fTarget->HandleMouseDown(theEvent, partCode, theWindow); 
  133.     }
  134.  
  135. }// end MouseDown member function 
  136.  
  137.  
  138. void DApplication::NullEvent(EventRecord *theEvent)
  139. {
  140.     fTarget->HandleNullEvent(theEvent);
  141.  
  142.     if( fDeadHandlers->NumItems())
  143.         FlushDeadHandlers();
  144. }
  145.  
  146.  
  147. void DApplication::ActivateEvt(EventRecord *theEvent)
  148. {
  149.     short windowKind;
  150.     
  151.     windowKind = ((WindowPeek) theEvent->message)->windowKind;
  152.     if (windowKind >= userKind)
  153.     {
  154.         fTarget = (DEventHandler *) GetWRefCon((WindowPtr)theEvent->message);
  155.         fTarget->HandleActivateEvt(theEvent);
  156.     }
  157.     else
  158.         fTarget = this;
  159.     // I'm making the same assumption that userKind windows are DWidnows which
  160.     // is a safe assumption as DWindows are created by the user.
  161.     // windows under sys 7 will be DWindows.
  162.     
  163.     // whatch for active windows not being the front one, if this happens
  164.     // then a check for frontness needs to be put here and if window isn't 
  165.     // the front on then bring it up.
  166. }
  167.  
  168.  
  169.  
  170. void DApplication::AutoKey(EventRecord *theEvent)
  171. {
  172.     fTarget->HandleAutoKey(theEvent);
  173.     // BIG STUBB!!!!
  174. }
  175.  
  176.  
  177.  
  178. void DApplication::KeyDown(EventRecord *theEvent)                    
  179. {
  180.     char key;
  181.     long result;
  182.     
  183.     key = (char) theEvent->message & charCodeMask;
  184.     if( theEvent->modifiers & cmdKey )    //command key!!
  185.     {
  186.         ClearMenus();
  187.         fTarget->SetUpMenues();
  188.         
  189.         result = MenuKey(key);
  190.         if(HiWrd(result) != 0)
  191.         {
  192.             fTarget->HandleMenuChoice(HiWrd(result), LoWrd(result) );
  193.             HiliteMenu(0);
  194.         }
  195.     }
  196.     else // not menu command key
  197.         fTarget->HandleKeyDown(theEvent);
  198.  
  199. }
  200.  
  201.  
  202.  
  203. void DApplication::DiskEvt(EventRecord *theEvent)
  204. {
  205.     Point mountPoint;
  206.     short    err;
  207.     
  208.     if (HiWrd(theEvent->message) != noErr) 
  209.     {
  210.         SetPt(&mountPoint, kDILeft, kDITop);
  211.         err = DIBadMount(mountPoint, theEvent->message);
  212.     }
  213.     fTarget->HandleDiskEvt(theEvent);
  214. }
  215.  
  216.  
  217.  
  218. void DApplication::HighLevelEvent(EventRecord *theEvent)
  219. {
  220.     AEProcessAppleEvent(theEvent);
  221.     
  222.     //fTarget->HandleHighLevelEvent(theEvent);
  223. }
  224.  
  225.  
  226. void DApplication::OSEvent(EventRecord *theEvent)
  227. {
  228.     switch ((theEvent->message >> 24) & 0xFF) 
  229.     {
  230.         case kMouseMovedMessage:
  231.             DisposeRgn( fCursorRgn);
  232.             fCursorRgn = NewRgn();
  233.             SetRectRgn(fCursorRgn, -32766, -32766, 32766, 32766); 
  234.             break;
  235.  
  236.         case kSuspendResumeMessage:
  237.             fInBackground = !(theEvent->message & resumeFlag);
  238.             if (fInBackground)    //going into the background
  239.             {
  240.                 fSleepVal = BACKGROUNDSLEEP; // we don't wan't any NULL events when we're in the background
  241.                 GiveClipToSystem();
  242.             }
  243.             else    // coming out of the background
  244.             {
  245.                 fSleepVal = SLEEPVAL;// put back to normal!!
  246.                 if(theEvent->message & convertClipboardFlag)
  247.                     GetClipFromSystem();
  248.                 // I don't do anything else for I know that the front window will
  249.                 // be getting an activate event next loop!!!
  250.             }
  251.             break;
  252.     }
  253.     fTarget->HandleOSEvent(theEvent);
  254. }
  255.  
  256.  
  257. void DApplication::UpdateEvt(EventRecord *theEvent)
  258. {
  259.     DWindow *upDateWindow;
  260.     short windowKind;
  261.     
  262.     windowKind = ((WindowPeek) theEvent->message)->windowKind;
  263.  
  264.     // I'm making the same assumption that userKind windows are DWidnows which
  265.     // is a safe assumption as DWindows are created by the user
  266.     // windows under sys 7 will be DWindows.  This is a bit of a risk hear, if
  267.     // the window is not in my appliction plane (which shouldn't happen) this 
  268.     // will brake.
  269.  
  270.     if (windowKind >= userKind)
  271.     {
  272.         upDateWindow = (DWindow *) GetWRefCon((WindowPtr)theEvent->message);
  273.         gPassItOn = FALSE;
  274.         upDateWindow->HandleUpdateEvt(theEvent);
  275.     }
  276.     gPassItOn = TRUE;
  277.     
  278. }
  279.  
  280.  
  281.  
  282. //
  283. // The following section of code is in support of the multiple
  284. // event handling object modle used in the DinkClass library
  285. //
  286.  
  287.  
  288. // Itterate over the list of deadHandlers event hadlers and delete
  289. // them all.  It is assumed that they have all cleaned up after
  290. // themselves and its ok to puff them.
  291. Boolean DApplication::FlushDeadHandlers(void)
  292. {
  293.     DEventHandler *nextHandler;
  294.     
  295.     fIterator->Init(fDeadHandlers);
  296.     
  297.     // First remove the dead handlers from the event hadler list (see bellow 
  298.     // for WHY they haven't been removed already) then delete them.  The error
  299.     // checking (like is nextHandler in the list of fEventHandlers? or fDeadHandlers?)
  300.     // is done in RemoveItem, but we have to be carefull with that delete guy.  
  301.     // He'll nuke you if given any excuse.
  302.     
  303.     while( nextHandler = (DEventHandler *)fIterator->GetCurrentThenIncrement() )
  304.     {
  305.         fEventHandlers->RemoveItem(nextHandler);
  306.         
  307.         if( fDeadHandlers->RemoveItem(nextHandler) )
  308.             delete nextHandler;
  309.     }
  310.     return TRUE;
  311. }
  312.  
  313. // Take killMe out of the list of itsEventHandlers and
  314. // up-date the list pointers in that list and finaly
  315. // place that guy in the list of deadHandlers for flushing
  316.  
  317. Boolean DApplication::RemoveHandler( DEventHandler *killMe)
  318. {
  319.     DEventHandler *nextHandler;
  320.     
  321.     fIterator->Init(fEventHandlers);
  322.     
  323.     // First loop over the event hadlers and reset all refrences to killMe
  324.     // to killMe->fNextHandler.  Then if killMe is the fTarget reset that
  325.     // to point to either killMe->fNextHandler or gApplication 
  326.     // (if killMe->fNextHandler == NULL)
  327.     
  328.     while( nextHandler = (DEventHandler *)fIterator->GetCurrentThenIncrement() )
  329.     {
  330.         if (killMe == (nextHandler)->fNextHandler)
  331.              (nextHandler)->fNextHandler = killMe->fNextHandler;
  332.         if (killMe == fTarget)
  333.         {
  334.             if ( fTarget->fNextHandler)
  335.                  fTarget = killMe->fNextHandler;
  336.             else
  337.                 fTarget = gApplication;// ok for now but this may make dangleing pointers later!!!!!
  338.         }
  339.     }
  340.  
  341.     // I don't remove the killMe object form the fEventHandlers list at this point
  342.     // because if I did then the CleanUp() method which tells all the eventhandlers
  343.     // to kill themselvs would not work dew to side effects of objects killing themselves
  344.     // and telling thier dependents to do the same (eg DWindow->KillMeNext() does this)
  345.     //
  346.     // If I did remove the event handler from the fEventHandlers list then that
  347.     // list would change while an iterator was opperating on it,  resulting in the
  348.     // iteration getting lost in space.
  349.     
  350.     if( fEventHandlers->ItemInList(killMe) )
  351.     {
  352.         fDeadHandlers->AddItem( killMe );
  353.         return TRUE; // killMe is taken out of the picture and ready to die
  354.     }
  355.     else
  356.         return FALSE;
  357. }    
  358.  
  359.  
  360. Boolean DApplication::InstalHandler( DEventHandler *addMe)
  361. {
  362.     
  363.     if (fEventHandlers->ItemInList( addMe ) == FALSE)
  364.         fEventHandlers->AddItem( addMe );
  365.     return TRUE;
  366.  
  367. }    
  368.  
  369.  
  370. //
  371. // ClearMenus is a utility method which gets called by the first
  372. // crack mouse down DApplication method if the mouse event was in the 
  373. // menu bar.  I think this class of member function should be 
  374. // partitiond away from the rest of the class definition.
  375. //
  376.  
  377. void DApplication::ClearMenus()
  378. {
  379.     MenuHandle    menu;
  380.     int menuItem;
  381.     
  382.     menu = GetMHandle(rFileMenu);
  383.     for (menuItem=1; menuItem<=CountMItems(menu); menuItem++)
  384.     {
  385.         EnableMenuItem( menu, menuItem, FALSE);
  386.     }
  387.  
  388.     menu = GetMHandle(rEditMenu);
  389.     for (menuItem=1; menuItem<=CountMItems(menu); menuItem++)
  390.     {
  391.         EnableMenuItem( menu, menuItem, FALSE);
  392.     }
  393. }
  394.  
  395.